
#include <iostream>
#include <vector>
using namespace std;

#include <boost/core/ignore_unused.hpp>
#include <boost/pool/pool.hpp>
using namespace boost;

/**
 *  1、构造参数为，每次分配内存块的大小
 *  2、get_requested_size()返回内存块的大小
 *  3、malloc返回一块内存块
 *  4、ordered_malloc(size_type n)连续分配n块内存
 *  5、is_from(void* chunk) 是否为内存池分配出去的
 *  6、free 释放内存
 *  7、release_memory 释放未分配的内存
 *  8、purge_memory 释放所有内存
 */

static void case1()
{
    pool<> p1(sizeof(int)); // 参数为每次分配的大小
    int *p = static_cast<int *>(p1.malloc()); // malloc分配一块内存
    assert(p1.is_from(p));

    p1.free(p);
    for (int i = 0; i < 100; i++)
    {
        p1.ordered_malloc(10); // 连续分配10块内存
    }
}

#include <boost/pool/object_pool.hpp>
struct demo_class
{
public:
        int a, b, c;
        demo_class(int x = 1, int y = 2, int z = 3):a(x),b(y),c(z)
        {

        }
};

static void case2()
{
    object_pool<demo_class> p1;

    auto p = p1.malloc();
    assert(p1.is_from(p));
    assert(p->a!=1 || p->b!=2 || p->c!=3);
    cout<<p->a<<endl;
    cout<<p->b<<endl;
    cout<<p->c<<endl;

    p = p1.construct(7, 8, 9);
    assert(7 == p->a);

    object_pool<string> pls;
    for (int i = 0; i < 10; ++i)
    {
        string *ps = pls.construct("hello object_pool");
        cout<<*ps<<endl;
    }
}

template<typename P, typename ...Args>
inline typename P::element_type*
construct(P& p, Args&& ... args)
{
    typename P::element_type* mem = p.malloc();
    assert(0 != mem);

    new (mem) typename P::element_type(std::forward<Args>(args)...);
    return mem;
}

struct demo_class2
{
    demo_class2(int, int, int, int)
    {
        cout<<"demo_class ctor"<<endl;
    }
    ~demo_class2()
    {
        cout<<"demo_class dtor"<<endl;
    }
};

static void case3()
{
    object_pool<demo_class2> p1;
    auto d = construct(p1, 1, 2, 3, 4);
    boost::ignore_unused(d);
}

#define BOOST_POOL_NO_MT
#include <boost/pool/singleton_pool.hpp>
struct pool_tag{};
typedef singleton_pool<pool_tag, sizeof(int)> sp1;

static void case4()
{
    int *p = (int *)sp1::malloc();
    assert(sp1::is_from(p));
    sp1::release_memory();
}

#include <boost/pool/pool_alloc.hpp>
static void case5()
{
    vector<int, pool_allocator<int> > v;
    v.push_back(10);
    cout<<v.size();
}

int main()
{
    // case1();
    // case2();
    // case3();
    // case4();
    case5();
}

